package com.etooling.framework.controller;

import com.etooling.framework.entity.Employee;
import com.etooling.framework.entity.FileResource;
import com.etooling.framework.entity.FuncModule;
import com.etooling.framework.entity.LoginLog;
import com.etooling.framework.repository.*;
import com.etooling.framework.service.impl.RedisService;
import com.etooling.framework.svo.ReplyObj;
import com.etooling.framework.utils.PasswordRuleMgr;
import com.etooling.framework.utils.VerifyCodeUtils;
import com.etooling.framework.utils.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Slf4j
@Controller
@EnableAutoConfiguration
public class LoginController {
    @Autowired
    OrgRepository orgRepository;
    @Autowired
    LoginLogRepository loginLogRepository;
    @Autowired
    EmployeeRepository employeeRepository;
    @Autowired
    FuncModuleRepository funcModuleRepository;
    @Autowired
    FileResourceRepository fileResourceRepository;
    @Autowired
    RedisService redisService;

    private static final String REDIS_KEY_PREFIX = "zm_pdm_VerifyCode";

    @RequestMapping("/login")
    @ResponseBody
    ReplyObj login(HttpServletRequest request,
                   @RequestParam(defaultValue = "", required = false, value = "loginId") String loginId,
                   @RequestParam(defaultValue = "", required = false, value = "orgId") String orgId,
                   @RequestParam(defaultValue = "", required = false, value = "pwd") String pwd,
                   @RequestParam(defaultValue = "", required = false, value = "loginType") String loginType,
                   @RequestParam(defaultValue = "", required = false, value = "verifyCode") String verifyCode,
                   @RequestParam(defaultValue = "", required = false, value = "mobile") String mobile,
                   @RequestParam(defaultValue = "", required = false, value = "mobileVerifyCode") String mobileVerifyCode
    ) {
        LoginLog loginLog = new LoginLog();
        loginLog.setLoginId(loginId);
        loginLog.setRemoteIp(request.getRemoteAddr());
        loginLog.setLoginTime(new Date());
        loginLog.setLoginPwd(pwd);
        loginLog.setStatus("正常登录");
        loginLog.setLoginResults("登录失败");
        try {
            Object rand = request.getSession().getAttribute("rand");
            boolean verifyCodeExist = redisService.existsInRedis(REDIS_KEY_PREFIX + verifyCode);
            log.info("Redis验证码存在：" + verifyCodeExist);
            // log.info("验证码为：" + rand);
            // log.info("用户输入验证码为：" + verifyCode);
            // log.info("验证码校验结果：" + verifyCode.toLowerCase().equals(rand));
            // 管理系统登入验证
            // if (verifyCode.toLowerCase().equals(rand)) {
            if (verifyCodeExist) {
                if ("用户登录".equals(loginType) || "".equals(loginType)) {
                    Employee loginEmployee = employeeRepository.getOneByLoginId(loginId.trim());
                    loginLog.setEmployee(loginEmployee);
                    if (loginEmployee != null && "禁用".equals(loginEmployee.getStatus()) == false) {
                        String randomCode = loginEmployee.getRandCode();
                        String tmpPwd = pwd + randomCode;
                        String password = PasswordRuleMgr.getCryptoPassword(tmpPwd);
                        System.out.println(password);
                        if (password.equals(loginEmployee.getPwd()) || pwd.equals(loginEmployee.getPwd())) {
                            HashMap returnValues = new HashMap();
                            // 插入登录日志
                            String token = "";
                            token = WebUtils.setSessionValue(token, WebUtils.LOGIN_USER_KEY, loginEmployee.getId());
                            returnValues.put("loginEmployee", loginEmployee);

                            // 获取菜单Json
                            List<FuncModule> allList = funcModuleRepository.getModulesTreeByUserId(loginEmployee.getId());
                            // 整理成完成的树结构
                            List<FuncModule> resultList = new ArrayList<>();
                            if (CollectionUtils.isNotEmpty(allList)) {
                                Map<String, List<FuncModule>> groupByMap = allList.stream()
                                        .collect(Collectors.groupingBy(lt -> lt.getParentId()));
                                resultList = this.getTree(groupByMap, "root");
                            }
                            returnValues.put("userFuncModule", resultList);
                            // 将json转成对象
                            // 识别下划线变驼峰

                            token = WebUtils.setSessionValue(token, WebUtils.LOGIN_COMPANY_ID_KEY, loginEmployee.getCompanyId());
                            token = WebUtils.setSessionValue(token, WebUtils.LOGIN_ORG_ID_KEY, loginEmployee.getOrg().getId());


                            // 按钮功能控制
                            List<FuncModule> fmList = funcModuleRepository.getALLBtnFuncModules(loginEmployee.getId());
                            Map<String, Object> btnFuncModulesMap = new HashMap<>();
                            for (FuncModule fm : fmList) {
                                if (WebUtils.checkStr(fm.getUrl())) {
                                    btnFuncModulesMap.put(fm.getUrl(), fm);
                                }
                            }
                            returnValues.put("btnFuncModulesMap", btnFuncModulesMap);

                            // 拿对应的文件资源配置
                            FileResource fileResource = fileResourceRepository.getByApplyResource(loginEmployee.getCompanyId());
                            // 初始化所有角色
//                            String token = WebUtils.getToken(loginEmployee);
                            if (WebUtils.checkStr(fileResource)) {
                                returnValues.put("fileRootPath", fileResource.getBasePath());
                            }

                            returnValues.put("token", token);
                            loginLog.setLoginResults("正常登录");

                            return WebUtils.flushObjSuccess(returnValues);
                        } else {
                            loginLog.setLoginResults("密码错误！");
                            return WebUtils.flushFailure("密码错误！");
                        }
                    } else {
                        loginLog.setLoginResults("用户不存在");
                        return WebUtils.flushFailure("用户不存在！");
                    }
                } else {
                    // TODO:周志荣 make 2020/12/18 发送短信登录,后面再做*/1
                    loginLog.setStatus("异常登录");
                    loginLog.setLoginResults("登录失败");
                }
            } else {
                loginLog.setLoginResults("验证码错误");
                return WebUtils.flushFailure("验证码错误");
            }
        } catch (Exception e) {
            loginLog.setLoginResults("登录失败");
            e.printStackTrace();
            return WebUtils.flushFailure("数据异常");
        } finally {
            loginLogRepository.save(loginLog);
        }
        return WebUtils.flushFailure();
    }

    public List<FuncModule> getTree(Map<String, List<FuncModule>> allNodeMap, String parentId) {
        List<FuncModule> list = allNodeMap.get(parentId);
        List<FuncModule> allTree = new ArrayList<>();
        list = allNodeMap.get(parentId);
        if (list != null && list.size() > 0) {
            for (FuncModule item : list) {
                List<FuncModule> children = null;
                if (allNodeMap.containsKey(item.getId())) {
                    children = getTree(allNodeMap, item.getId());
                }
                if (CollectionUtils.isNotEmpty(children)) {
                    item.setChildren(children);
                }
                allTree.add(item);
            }
        }
        return allTree;
    }


    @RequestMapping("/getVerifyCode")
    public void getVerifyCode(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setContentType("image/jpeg");
            response.setDateHeader("Expires", 0);

            // 生成随机字串
            String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
            // 存入会话session
            HttpSession session = request.getSession(true);
            // System.out.println(verifyCode);
            session.setAttribute("rand", verifyCode.toLowerCase());
            redisService.saveToRedis(REDIS_KEY_PREFIX + verifyCode, verifyCode, 30, TimeUnit.MINUTES);
            log.info("验证码为：" + verifyCode);
            // 生成图片
            int w = 120, h = 30;
            VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @RequestMapping("/toReLogin")
    @ResponseBody
    public ReplyObj toReLogin(HttpServletRequest request, HttpServletResponse response) {
        ReplyObj ro = new ReplyObj();
        ro.setCode(407);
        ro.setMsg("登录超时，请重新登录");
        return ro;
    }


}
